package com.ubao.network.resp;

import java.io.ByteArrayInputStream;
import java.io.DataInputStream;
import java.io.EOFException;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.util.Enumeration;
import java.util.Hashtable;
import java.util.Vector;

import com.ubao.util.Drawer;

/**
 * 返回信息的解析方法类
 * <p>
 * Title:
 * </p>
 * 
 * <p>
 * Description:
 * </p>
 * 
 * <p>
 * Copyright: Copyright (c) 2008
 * </p>
 * 
 * <p>
 * Company:
 * </p>
 * 
 * @author not attributable
 * @version 1.0
 */
public class StructResponse {
    private DataInputStream in;

    private ByteArrayInputStream bin;

    private Hashtable hash;

    private Vector vec;

    private int size;

    public StructResponse(byte[] data) {
        bin = new ByteArrayInputStream(data);
        in = new DataInputStream(bin);
    }

    public StructResponse(byte[] data, boolean bTradeCipher) {
        hash = new Hashtable();
        vec = new Vector();
        readTradeData(data);

        Enumeration em = hash.keys();
        while (em.hasMoreElements()) {
            String key = (String) em.nextElement();
            String value = (String) hash.get(key);
        }
        this.getTable();
    }

    private boolean bTable = false;

    private int tableIndex = 0; // 表格数据的列数

    private void readTradeData(byte[] data) {
        int i = 0;
        try {
            for (; i < data.length; i++) {
                if (data[i] == 0x01) {
                    String s = new String(data, 0, i, "UTF-8");
                    if (bTable) {
                        vec.addElement(s);
                        if (tableIndex == 0) {
                            tableIndex = vec.size();
                        }
                    } else {
                        putInHash(s);
                    }
                    break;
                } else if (data[i] == 0x02) {
                    String s = new String(data, 0, i, "UTF-8");
                    if (bTable) {
                        vec.addElement(s);
                    } else {
                        putInHash(s);
                    }
                    break;
                } else if (data[i] == 0x03) {
                    bTable = true;
                    if (i > 0) {
                        String s = new String(data, 0, i, "UTF-8");
                        putInHash(s);
                    }
                    break;
                } else if (data[i] == 0x04) {
                    bTable = false;
                    String s = new String(data, 0, i, "UTF-8");
                    vec.addElement(s);
                    if (tableIndex == 0) {
                        tableIndex = vec.size();
                    }
                    break;
                }
            }

            String s = new String(data, 0, i, "UTF-8");
            putInHash(s);
        } catch (Exception ex) {
            ex.printStackTrace();
        }

        if (data.length - i - 1 > 0) {
            byte[] nData = new byte[data.length - i - 1];
            System.arraycopy(data, i + 1, nData, 0, data.length - i - 1);
            readTradeData(nData);
        }
    }

    private void putInHash(String s) {
        int index = s.indexOf("=");
        if (index >= 0) {
            String s1 = s.substring(0, index);
            String s2 = s.substring(index + 1, s.length());
            this.hash.put(s1, s2);
        }
    }

    public String getHashData(String key) {
        return (String) hash.get(key);
    }

    public String[][] getTable() {
        if (tableIndex <= 0) {
            return null;
        }

        int line = vec.size() / this.tableIndex;
        String[][] tmp = new String[line][tableIndex];
        // System.out.println("");
        for (int i = 0; i < line; i++) {
            for (int j = 0; j < tableIndex; j++) {
                tmp[i][j] = (String) vec.elementAt(i * tableIndex + j);
                // System.out.print("  " + tmp[i][j]);
            }
            // System.out.println("");
        }
        return tmp;
    }

    public int readLength() {
        size = readShort();

        // System.out.println("pacakge size = "+size);
        return size;
    }

    public int getSize() {
        return size;
    }

    public boolean readBoolean() {
        try {
            return in.readBoolean();
        } catch (Exception ex) {

            throw new RuntimeException();
        }
    }

    public boolean[] readBooleans() {
        boolean[] v = new boolean[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = readBoolean();
        }
        return v;
    }

    public boolean[][] readBooleans2() {
        int length = readLength();
        if (length == 0) {
            return new boolean[0][];
        }
        boolean[][] v = new boolean[length][readLength()];
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[0].length; j++) {
                v[i][j] = readBoolean();
            }
        }
        return v;
    }

    public int readByte() {
        try {
            return in.readByte();
        } catch (Exception ex) {
            throw new RuntimeException();
        }
    }

    public int[] readBytes() {
        int[] v = new int[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = readByte();
        }
        return v;
    }

    public int[][] readBytes2() {
        int length = readLength();
        if (length == 0) {
            return new int[0][];
        }
        int[][] v = new int[length][readLength()];
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[0].length; j++) {
                v[i][j] = readByte();
            }
        }
        return v;
    }

    public int readShort() {
        try {
            // System.out.println("read first byte in short");
            int v2 = in.read();
            // System.out.println("read second byte in short");
            int v1 = in.read();
            // System.out.println("read third byte in short");
            if ((v1 | v2) < 0) {
                throw new EOFException();
            }
            // Log.d("read", "v1 << 8="+(v1 << 8));
            // Log.d("read", "v2 << 0="+(v2 << 0));
            return (short)((v1 << 8) + (v2 << 0));
        } catch (IOException ex) {
            return 0;
        }

    }

    public int[] readShorts() {
        int[] v = new int[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = readShort();
        }
        return v;
    }

    public int[][] readShorts2() {
        int length = readLength();
        if (length == 0) {
            return new int[0][];
        }
        int[][] v = new int[length][readLength()];
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[0].length; j++) {
                v[i][j] = readShort();
            }
        }
        return v;
    }

    /**
     * 解析新信息地雷的返回股票
     * 
     * @return
     */
    public String readStock() {
        int marketstock = readInt();
        String code = "";
        int market = marketstock >>> 0 & 0x3f;
        if (market == 1) {
            code += "SH";
        } else if (market == 0) {
            code += "SZ";
        } else if (market == 45) {
            code += "BI";
        }
        marketstock = marketstock >>> 6;
        int num6 = marketstock & 0x0f;
        int num5 = marketstock >>> 4 & 0x0f;
        int num4 = marketstock >>> 8 & 0x0f;
        int num3 = marketstock >>> 12 & 0x0f;
        int num2 = marketstock >>> 16 & 0x0f;
        int num1 = marketstock >>> 20 & 0x0f;
        if (market != 45) {
            code += String.valueOf(num1) + String.valueOf(num2) + String.valueOf(num3) + String.valueOf(num4)
                    + String.valueOf(num5) + String.valueOf(num6);
        } else {
            code += String.valueOf(num1) + String.valueOf(num2) + String.valueOf(num3) + String.valueOf(num4);

        }
        return code;
    }

    public long readLargeInt() {
        return Drawer.parseLargeInt(readInt());
    }

    /**
     * 用于资讯
     * 
     * @return
     */
    public String readCodeWithMarket() {
        String code = readStringFromByteArray(7);

        int marketType = readByte();
        switch (marketType) {
        case 0:
            return "SZ" + code;

        case 1:
            return "SH" + code;

        case 90:
            return "BI" + code;
        }

        return null;
    }

    public int readInt() {
        try {
            int v4 = in.read();// dd
            int v3 = in.read();// b4
            int v2 = in.read();// 4
            int v1 = in.read();// 0
            if ((v1 | v2 | v3 | v4) < 0) {
                throw new EOFException();
            }
            int x1 = v1 << 24;
            int x2 = v2 << 16;
            int x3 = v3 << 8;
            int x4 = v4 << 0;
            int sum = x1 + x2 + x3 + x4;
            return sum;
            // return ((v1 << 24) + (v2 << 16) + (v3 << 8) + (v4 << 0));
        } catch (IOException ex) {
            return 0;
        }
    }

    public int[] readInts() {
        int[] v = new int[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = readInt();
        }
        return v;
    }

    public int[][] readInts2() {
        int length = readLength();
        if (length == 0) {
            return new int[0][];
        }
        int[][] v = new int[length][readLength()];
        for (int i = 0; i < v.length; i++) {
            for (int j = 0; j < v[0].length; j++) {
                v[i][j] = readInt();
            }
        }
        return v;
    }

    public int[] readNumbers() {
        int size = readByte();
        if (size == 1) {
            return readBytes();
        }
        if (size == 2) {
            return readShorts();
        }
        return readInts();
    }

    public int[][] readNumbers2() {
        int size = readByte();
        if (size == 1) {
            return readBytes2();
        }
        if (size == 2) {
            return readShorts2();
        }
        return readInts2();
    }

    public long readLong() {
        try {
            long v8 = in.read();
            long v7 = in.read();
            long v6 = in.read();
            long v5 = in.read();
            long v4 = in.read();
            long v3 = in.read();
            long v2 = in.read();
            long v1 = in.read();
            if ((v1 | v2 | v3 | v4 | v5 | v6 | v7 | v8) < 0) {
                throw new EOFException();
			}
			return (long) ((v1 << 56) + (v2 << 48) + (v3 << 40) + (v4 << 32)
					+ (v5 << 24) + (v6 << 16) + (v7 << 8) + (v8 << 0));
		} catch (IOException ex) {
            return 0;
        }
    }

    public String readString() {
        try {

            int len = readLength();
            byte[] b = new byte[len];
            in.read(b);
            return new String(b, "UTF-8");
        } catch (IOException ex) {
            return null;
        }
    }

    public String readAnsiString() {
        try {

            int len = readLength();
            byte[] b = new byte[len];
            in.read(b);
            return new String(b);
        } catch (IOException ex) {
            return null;
        }
    }

    public String readString(int num) {
        try {

            int len = num;
            byte[] b = new byte[len];
            in.read(b);
            return new String(b, "GBK");
        } catch (IOException ex) {
            return null;
        }
    }

    public String readStringNew() {
        try {

            int len = readLength();
            byte[] b = new byte[len];
            in.read(b);
            return new String(b, "UTF-8");
        } catch (IOException ex) {
            return null;
        }
    }

    public String[] readStrings() {
        String[] v = new String[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = readString();
        }
        return v;
    }

    public String[][] readStrings2() {
        String[][] v = new String[readLength()][];
        for (int i = 0; i < v.length; i++) {
            v[i] = readStrings();
        }
        return v;
    }

    public byte[] readByteArrayWithEndFlag() {
        byte[] v = new byte[readLength() + 1];
        for (int i = 0; i < v.length; i++) {
            v[i] = (byte) readByte();
        }
        return v;
    }

    public byte[] readByteArray() {
        byte[] v = new byte[readLength()];
        for (int i = 0; i < v.length; i++) {
            v[i] = (byte) readByte();
        }
        return v;
    }

    /**
     * added by wyp 20110329
     */
    public byte[] readByteArray(int length) {
        final byte[] bytes = new byte[length];
        for (int i = 0; i < length; i++) {
            bytes[i] = (byte) readByte();
        }
        return bytes;
    }

    public String readStringFromByteArray(int length) {
        return readStringFromByteArray(length, null);
    }

    public String readStringFromByteArray(int length, String enc) {
        final byte[] bytes = new byte[length + 1];
        boolean end = false;
        for (int i = 0; i < length; i++) {
            if (end) {
                readByte();
            } else {
                bytes[i] = (byte) readByte();
            }

            if (bytes[i] == '\0') {
                end = true;
            }
        }
        bytes[length] = '\0';

        if (enc == null) {
            return new String(bytes);
        }

        try {
            return new String(bytes, enc);
        } catch (UnsupportedEncodingException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return null;
    }

    public byte[] getOthers() {
        try {
            int num = in.available();
            byte[] tmp = new byte[num];
            for (int i = 0; i < num; i++) {
                tmp[i] = in.readByte();
            }
            return tmp;
        } catch (IOException ex) {
            return null;
        }
    }

    public Vector readVector() {
        int num = readLength();
        // Log.d("readVector", "num = "+num);
        Vector v = new Vector(num);
        for (int i = 0; i < num; i++) {
            v.addElement(readString());
        }
        return v;
    }

    public void cloese() {
        try {
            if (in != null) {
                in.close();
            }
            if (bin != null) {
                bin.close();
            }
            in = null;
            bin = null;
        } catch (IOException ex) {
        }
    }

    public int getAvailable() {
        try {
            if (bin == null) {
                return 0;
            }
            return bin.available();
        } catch (Exception e) {
            e.printStackTrace();
            return -1;
        }
    }

    public boolean isAvailable() {
        try {
            return in.available() > 0;
        } catch (IOException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }

        return false;
    }
}
